home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / trace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  5.7 KB  |  269 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <time.h>
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "iface.h"
  7. #include "trace.h"
  8. #include "commands.h"
  9.  
  10. static void ascii_dump __ARGS((FILE *fp,struct mbuf **bpp));
  11. static void ctohex __ARGS((char *buf,int16 c));
  12. static void fmtline __ARGS((FILE *fp,int16 addr,char *buf,int16 len));
  13. static void hex_dump __ARGS((FILE *fp,struct mbuf **bpp));
  14. static void showtrace __ARGS((struct iface *ifp));
  15.  
  16. /* Redefined here so that programs calling dump in the library won't pull
  17.  * in the rest of the package
  18.  */
  19. static char nospace[] = "No space!!\n";
  20.  
  21. void dump(iface,direction,type,bp)
  22. register struct iface *iface;
  23. int direction;
  24. unsigned type;
  25. struct mbuf *bp;
  26. {
  27.     struct mbuf *tbp;
  28.     void (*func) __ARGS((FILE *,struct mbuf **,int));
  29.     int16 size;
  30.     time_t timer;
  31.     char *cp;
  32.  
  33.     if(iface == NULL || (iface->trace & direction) == 0)
  34.         return;    /* Nothing to trace */
  35.  
  36.     switch(direction){
  37.     case IF_TRACE_IN:
  38.         if((iface->trace & IF_TRACE_NOBC)
  39.          && (Tracef[type].addrtest != NULLFP)
  40.          && (*Tracef[type].addrtest)(iface,bp) == 0)
  41.             return;        /* broadcasts are suppressed */
  42.         time(&timer);
  43.         cp = ctime(&timer);
  44.         cp[24] = '\0';
  45.         fprintf(iface->trfp,"\n\x0f%s - %s RX:\n",cp,iface->name);
  46.         break;
  47.     case IF_TRACE_OUT:
  48.         time(&timer);
  49.         cp = ctime(&timer);
  50.         cp[24] = '\0';
  51.         fprintf(iface->trfp,"\n\x0f%s - %s TX:\n",cp,iface->name);
  52.         break;
  53.     }
  54.     if(bp == NULLBUF || (size = len_p(bp)) == 0){
  55.         fprintf(iface->trfp,"empty packet!!\n");
  56.         return;
  57.     }
  58.  
  59.     if(type < NLTYPE)
  60.         func = Tracef[type].tracef;
  61.     else
  62.         func = NULLVFP;
  63.  
  64.     dup_p(&tbp,bp,0,size);
  65.     if(tbp == NULLBUF){
  66.         fprintf(iface->trfp,nospace);
  67.         return;
  68.     }
  69.     if(func != NULLVFP)
  70.         (*func)(iface->trfp,&tbp,1);
  71.     if(iface->trace & IF_TRACE_ASCII){
  72.         /* Dump only data portion of packet in ascii */
  73.         ascii_dump(iface->trfp,&tbp);
  74.     } else if(iface->trace & IF_TRACE_HEX){
  75.         /* Dump entire packet in hex/ascii */
  76.         free_p(tbp);
  77.         dup_p(&tbp,bp,0,len_p(bp));
  78.         if(tbp != NULLBUF)
  79.             hex_dump(iface->trfp,&tbp);
  80.         else
  81.             fprintf(iface->trfp,nospace);
  82.     }
  83.     free_p(tbp);
  84. }
  85.  
  86. /* Dump packet bytes, no interpretation */
  87. void
  88. raw_dump(iface,direction,bp)
  89. struct iface *iface;
  90. int direction;
  91. struct mbuf *bp;
  92. {
  93.     struct mbuf *tbp;
  94.  
  95.     /* Dump entire packet in hex/ascii */
  96.     fprintf(iface->trfp,"******* raw packet dump (%s %s)\n",
  97.         ((direction & IF_TRACE_OUT) ? "send" : "recv"),iface->name);
  98.     dup_p(&tbp,bp,0,len_p(bp));
  99.     if(tbp != NULLBUF)
  100.         hex_dump(iface->trfp,&tbp);
  101.     else
  102.         fprintf(iface->trfp,nospace);
  103.     fprintf(iface->trfp,"*******\n");
  104.     free_p(tbp);
  105.     return;
  106. }
  107.  
  108. /* Dump an mbuf in hex */
  109. static void hex_dump(fp,bpp)
  110. FILE *fp;
  111. register struct mbuf **bpp;
  112. {
  113.     int16 n;
  114.     int16 address;
  115.     char buf[16];
  116.  
  117.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  118.         return;
  119.  
  120.     address = 0;
  121.     while((n = pullup(bpp,buf,sizeof(buf))) != 0){
  122.         fmtline(fp,address,buf,n);
  123.         address += n;
  124.     }
  125. }
  126.  
  127. /* Dump an mbuf in ascii */
  128. static void ascii_dump(fp,bpp)
  129. FILE *fp;
  130. register struct mbuf **bpp;
  131. {
  132.     char c;
  133.     register int16 tot;
  134.  
  135.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  136.         return;
  137.  
  138.     tot = 0;
  139.     while(pullup(bpp,&c,1) == 1){
  140.         if((tot % 64) == 0)
  141.             fprintf(fp,"%04x  ",tot);
  142.         fputc(isprint(uchar(c)) ? c : '.',fp);
  143.         if((++tot % 64) == 0)
  144.             fprintf(fp,"\n");
  145.     }
  146.     if((tot % 64) != 0)
  147.         fprintf(fp,"\n");
  148.     fprintf(fp,"BYTES: %d\n",tot);
  149. }
  150.  
  151. /* Print a buffer up to 16 bytes long in formatted hex with ascii
  152.  * translation, e.g.,
  153.  * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f  0123456789:;<=>?
  154.  */
  155. static void fmtline(fp,addr,buf,len)
  156. FILE *fp;
  157. int16 addr;
  158. char *buf;
  159. int16 len;
  160. {
  161.     char line[80];
  162.     register char *aptr,*cptr;
  163.     register char c;
  164.  
  165.     memset(line,' ',sizeof(line));
  166.     ctohex(line,(int16)hibyte(addr));
  167.     ctohex(line+2,(int16)lobyte(addr));
  168.     aptr = &line[6];
  169.     cptr = &line[55];
  170.     while(len-- != 0){
  171.         c = *buf++;
  172.         ctohex(aptr,(int16)uchar(c));
  173.         aptr += 3;
  174.         c &= 0x7f;
  175.         *cptr++ = isprint(uchar(c)) ? c : '-';
  176.     }
  177.     *cptr++ = '\n';
  178.     fwrite(line,1,(unsigned)(cptr-line),fp);
  179. }
  180.  
  181. /* Convert byte to two ascii-hex characters */
  182. static void ctohex(buf,c)
  183. register char *buf;
  184. register int16 c;
  185. {
  186.     static char hex[] = "0123456789abcdef";
  187.  
  188.     *buf++ = hex[hinibble(c)];
  189.     *buf = hex[lonibble(c)];
  190. }
  191.  
  192. /* Modify or displace interface trace flags */
  193. int dotrace(argc,argv,p)
  194. int argc;
  195. char *argv[];
  196. void *p;
  197. {
  198.     struct iface *ifp;
  199.  
  200.     if(argc < 2){
  201.         for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  202.             showtrace(ifp);
  203.         return 0;
  204.     }
  205.     if((ifp = if_lookup(argv[1])) == NULLIF){
  206.         tprintf(Badinterface,argv[1]);
  207.         return 1;
  208.     }
  209.     if(ifp->port){
  210.         tprintf("No trace on this interface - use master.\n");
  211.         return 1;
  212.     }
  213.     if(argc >= 3)
  214.         ifp->trace = htoi(argv[2]);
  215.  
  216.     /* Always default to stdout unless trace file is given */
  217.     if(ifp->trfp != NULLFILE && ifp->trfp != stdout)
  218.         fclose(ifp->trfp);
  219.     ifp->trfp = stdout;
  220.     if(ifp->trfile != NULLCHAR)
  221.         free(ifp->trfile);
  222.     ifp->trfile = NULLCHAR;
  223.  
  224.     if(argc >= 4){
  225.         if((ifp->trfp = fopen(argv[3],APPEND_TEXT)) == NULLFILE){
  226.             tprintf("Can't write to %s\n",argv[3]);
  227.             ifp->trfp = stdout;
  228.         } else {
  229.             ifp->trfile = strdup(argv[3]);
  230.         }
  231.     }
  232.     showtrace(ifp);
  233.     return 0;
  234. }
  235.  
  236. /* Display the trace flags for a particular interface */
  237. static void showtrace(ifp)
  238. register struct iface *ifp;
  239. {
  240.     if(ifp == NULLIF)
  241.         return;
  242.     tprintf("%s:",ifp->name);
  243.     if(ifp->port){
  244.         tprintf(" trace on master interface only.\n");
  245.         return;
  246.     }
  247.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  248.         if(ifp->trace & IF_TRACE_IN)
  249.             tprintf(" input");
  250.         if(ifp->trace & IF_TRACE_OUT)
  251.             tprintf(" output");
  252.  
  253.         if(ifp->trace & IF_TRACE_NOBC)
  254.             tprintf(" - no broadcasts");
  255.  
  256.         if(ifp->trace & IF_TRACE_HEX)
  257.             tprintf(" (Hex/ASCII dump)");
  258.         else if(ifp->trace & IF_TRACE_ASCII)
  259.             tprintf(" (ASCII dump)");
  260.         else
  261.             tprintf(" (headers only)");
  262.         if(ifp->trfile != NULLCHAR)
  263.             tprintf(" trace file: %s",ifp->trfile);
  264.         tprintf("\n");
  265.     } else
  266.         tprintf(" tracing off\n");
  267. }
  268.  
  269.